/**
 * Project Name:template-web
 * File Name   :RequestDispatcher.java
 * Package Name:org.cn.template.component.web.servlet
 * Date:2015年9月27日下午4:56:03
 * Copyright (c) 2015, http://my.oschina.net/httpssl All Rights Reserved.
 *
*/

package org.cn.template.component.web.servlet;

import java.io.IOException;
import java.util.Date;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.cn.template.component.domain.Message;
import org.cn.template.component.enums.MessageStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerExecutionChain;

import com.alibaba.fastjson.JSON;


/**
 * ClassName:RequestDispatcher <br/>
 * Function :TODO ADD FUNCTION. <br/>
 * Reason	:TODO ADD REASON. <br/>
 * Date     :2015年9月27日 下午4:56:03 <br/>
 * @author  :http://my.oschina.net/httpssl
 * @email   :491835898@QQ.COM
 * @since   :JDK 1.7
 * @see 	 
 */
public class RequestDispatcher extends DispatcherServlet
{
private static final long serialVersionUID = 1L;
	
	private final Logger logger = LoggerFactory.getLogger(RequestDispatcher.class);

	@Override
	public void init(ServletConfig config) throws ServletException
	{
		super.init(config);
		super.setDetectAllHandlerExceptionResolvers(false);
	}

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{

		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;
		try {
			mappedHandler = super.getHandler(processedRequest);
			if ((mappedHandler == null) || (mappedHandler.getHandler() == null)) {
				logger.warn("req " + request.getRequestURL() + ".....uri " + getRequestUri(request));
				response.sendError(404);
				return;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		processedRequest = checkMultipart(request);
		boolean isAjaxRequest = isAjaxRequest(request);
		dispatcherService(isAjaxRequest,request, response);
	}

	private void dispatcherService(boolean isAjaxRequest,HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		try {
			super.service(request, response);
		} catch (Exception e) {
			/*
			 * 在这里对系统的异常类型进行判断,然后做不同的处理
			 * 当请求是ajax时,一般返回{state:0,message:e.getMessage}
			 */
			if(isAjaxRequest){
				Message msg = new Message(MessageStatus.error,e.getMessage());
				msg.setTime(new Date());
				response.setCharacterEncoding("UTF-8");
				response.setHeader("Cache-Control", "no-cache");
				response.getWriter().write(JSON.toJSONString(msg));
				response.getWriter().flush();
				response.getWriter().close();
			}else{
				forwardErrorPage(request,response,e.getMessage());
			}
		}
	}
	
	private final static String ISAJAX = "isajax";

	private static boolean isAjaxRequest(HttpServletRequest request)
	{
		String isajax = request.getParameter(ISAJAX);
		if (StringUtils.isNotEmpty(isajax)) {
			return "1".equals(isajax);
		} else {
			return "XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With"));
		}
	}

	private static String getRequestUri(HttpServletRequest request)
	{
		String uri = (String) request.getAttribute("javax.servlet.include.request_uri");
		if (uri == null) {
			uri = request.getRequestURI();
		}
		return uri;
	}
	
	private void forwardErrorPage(HttpServletRequest request,HttpServletResponse response,String message) throws ServletException, IOException{
		logger.error(message);
		request.setAttribute("message",message);
		request.getRequestDispatcher("/500.jsp").forward(request, response);
	}
}
